<script setup>
import { computed, ref } from "vue";
import {
    PlusRound,
    DeleteOutlineRound,
    DriveFileRenameOutlineOutlined,
    ArrowCircleUpRound,
    ArrowCircleDownRound,
} from "@vicons/material";
import NoteCard from "@/components/note/NoteCard.vue";
import { renderIcon } from "@/utils/render-icon";
import { toHref } from "@/utils/to_path";
import DeleteRemindWindow from "@/components/delete/RemindWindow.vue";
import RenameWindow from "@/components/rename/RenameWindow.vue";
import noteServeRequest from "@/utils/request";
import noteApi from '@/utils/api/noteApi'


// 笔记列表
const notes = ref([]);

// 发送获取笔记请求
const getNotes = async () => {
    noteServeRequest(noteApi.getNote).then((response) => {
        notes.value = response.data; // 笔记列表
    })
};

getNotes()

// 右键菜单
const contextMenu = ref({
    show: false, // 是否显示
    x: 0, // 水平位置
    y: 0, // 垂直位置
    top: false, // 是否显示置顶选项
    title: "", // 笔记标题
    id: null, // 笔记编号
});

// 右键菜单选项， 展示笔记菜单选项
const contentMenuOptions = computed(() => {
    return [
        {
            key: "rename",
            label: "重命名",
            icon: renderIcon(DriveFileRenameOutlineOutlined),
        },
        {
            key: "delete",
            label: "删除",
            icon: renderIcon(DeleteOutlineRound),
        },
        {
            key: "top",
            label: "置顶",
            icon: renderIcon(ArrowCircleUpRound),
            show: contextMenu.value.top,
        },
        {
            key: "cancle-top",
            label: "取消置顶",
            icon: renderIcon(ArrowCircleDownRound),
            show: !contextMenu.value.top,
        },
    ];
});

/**
 *  显示右键菜单
 * @param {*} e 事件
 * @param {Boolean} top 该文件是否处于置顶状态
 * @param {String} title 笔记标题
 * @param {Number} id 笔记编号
 */
const showContextMenu = (e, top, title, id) => {
    contextMenu.value.show = false; // 关闭之前右键菜单
    setTimeout(() => {
        contextMenu.value.x = e.clientX; // 确定水平位置
        contextMenu.value.y = e.clientY; // 确定垂直位置
        contextMenu.value.top = !top; // 置顶和取消置顶的显示
        contextMenu.value.title = title; // 笔记的标题
        contextMenu.value.id = id; // 笔记的编号
        contextMenu.value.show = true; // 显示右键菜单
    }, 100);
};

// 删除提醒框组件实例
const deleteRmindWindowRef = ref(null);

// 重命名窗口的实例对象
const renameWindowRef = ref(null);

// 右键菜单选项被选中
const selectDropdownOption = (key, option) => {
    if (key === "delete") {
        // 删除选项 -- 显示删除提醒框
        deleteRmindWindowRef.value.changeShowValue(true);
    } else if (key === "rename") {
        // 重命名选项 -- 显示重命名窗口
        renameWindowRef.value.changeShowValue(true);
    } else if (key === "top" || key === "cancle-top") {
        // 置顶笔记或者取消置顶笔记
        toTop();
    }
};

// 置顶 / 取消置顶
const toTop = async () => {
    let isTop = contextMenu.value.top; // 是否时置顶操作
    // 请求 API
    let topNoteAPI = { ...noteApi.topNote };
    // 请求名称
    topNoteAPI.name = isTop ? topNoteAPI.name[0] : topNoteAPI.name[1]
    // 请求参数
    topNoteAPI.params = {
        isTop,
        noteId: contextMenu.value.id,
    }
    // 发送请求
    noteServeRequest(topNoteAPI).then((response) => {
        if (response) getNotes(); // 重新获取笔记列表
    })
};

// 是否重新加载编辑的笔记
const isChangeEditNote = ref(0) // 0 不需要改变，1：重新加载，2：关闭

/**
 * 去删除笔记
 * @param {Boolean} isComplete 是否彻底删除
 */
const toDelete = async (isComplete) => {
    // 请求 API
    let deleteNoteAPI = { ...noteApi.deleteNote };
    // 请求名称
    deleteNoteAPI.name = isComplete ? deleteNoteAPI.name[1] : deleteNoteAPI.name[0]
    // 请求参数
    deleteNoteAPI.params = {
        complete: isComplete,
        noteId: contextMenu.value.id,
        recycleBin: false,
    }
    // 发送请求
    noteServeRequest(deleteNoteAPI).then((response) => {
        if (!response) return
        getNotes(); // 重新获取笔记列表
        isChangeEditNote.value = 2 // 通知子组件我删除了笔记
        setTimeout(() => { isChangeEditNote.value = 0 }, 1500)
    })
};

/**
 * 重命名笔记
 * @param {String} afterName 重命名后的名字
 */
const toRename = async (afterName) => {
    // 请求 API
    let renameNoteAPI = { ...noteApi.renameNote };
    // 请求参数
    renameNoteAPI.params = {
        noteId: contextMenu.value.id,
        title: afterName,
    }
    // 发送请求
    noteServeRequest(renameNoteAPI).then((response) => {
        if (!response) return
        getNotes(); // 重新获取笔记列表
        isChangeEditNote.value = 1 // 通知子组件我重名了笔记
        setTimeout(() => { isChangeEditNote.value = 0 }, 1500)
    })
};

/**
 * 创建笔记
 */
const toCreate = async () => {
    noteServeRequest(noteApi.createNote).then((response) => {
        if (!response) return
        getNotes(); // 重新获取笔记列表
        toHref(`/note/edit/${response.data}`) // 跳转至编辑笔记的页面
    })
};
</script>

<template>
    <n-layout has-sider position="absolute">
        <n-layout-sider bordered show-trigger :width="340" :collapsed-width="0">
            <n-scrollbar @scroll="contextMenu.show = false">
                <!-- 标题区域 -->
                <n-card :bordered="false" id="note-title-area">
                    <template #action>
                        <n-space justify="space-between" align="center">
                            <h3 style="margin: 0;">笔记列表</h3>
                            <n-button circle type="success" @click="toCreate">
                                <n-icon :size="22" :component="PlusRound"></n-icon>
                            </n-button>
                        </n-space>
                    </template>
                </n-card>
                <!-- 笔记列表区域 -->
                <n-list hoverable clickable>
                    <n-list-item v-for="b in notes" :key="b.id" @click="toHref('/note/edit/' + b.id)"
                        @contextmenu.prevent="showContextMenu($event, !!b.top, b.title, b.id)">
                        <note-card :id="b.id" :title="b.title" :desc="b.body" :top="!!b.top" :time="b.updateTime" />
                    </n-list-item>
                </n-list>
            </n-scrollbar>
        </n-layout-sider>
        <n-layout-content embedded>
            <!-- 路由视图 -->
            <router-view @save="getNotes" :nid="contextMenu.id" :change="isChangeEditNote" />
        </n-layout-content>
    </n-layout>

    <!-- 笔记的右键菜单 -->
    <n-dropdown trigger="manual" placement="bottom-start" :x="contextMenu.x" :y="contextMenu.y"
        v-model:show="contextMenu.show" :options="contentMenuOptions" @clickoutside="contextMenu.show = false"
        @select="selectDropdownOption" />

    <!-- 删除提醒框 -->
    <delete-remind-window ref="deleteRmindWindowRef" :title="contextMenu.title" @delete="toDelete" />

    <!-- 重命名模态框 -->
    <rename-window ref="renameWindowRef" title="重命名笔记" :original-name="contextMenu.title" @rename="toRename" />
</template>

<style scoped>
aside.n-layout-sider :deep(div.n-layout-toggle-button) {
    transition: right 1s;
}

aside.n-layout-sider.n-layout-sider--collapsed :deep(div.n-layout-toggle-button) {
    right: -30px;
}

div.n-card#note-title-area {
    width: calc(100% - 1px);
    position: sticky;
    top: 0;
    left: 0;
    z-index: 1;
}
</style>